package cn.buk.tms.dao;

import cn.buk.tms.entity.bill.*;

import jakarta.persistence.EntityManager;
import java.util.List;

import static cn.buk.tms.common.constant.TmsOrderConstant.*;

/**
 * 将基础的账单DAO操作放置于该抽象类中
 * @author yfdai
 */
public class AbstractBillDao extends AbstractDao {

  protected BillInfo doGetBillInfo(int id, boolean fetchChild) {

    BillInfo billInfo = em.find(BillInfo.class, id);
    if (billInfo == null) {
      return null;
    }

    em.refresh(billInfo);

    if (fetchChild) {
      final int enterpriseId = billInfo.getEnterpriseId();

      if (BILL_TYPE_FLIGHT.equals(billInfo.getBillType())) {
        // flight ticket
        List<BillFlightTicket> tickets = searchBillFlightTickets(em, enterpriseId, billInfo.getBillNum());
        billInfo.setTickets(tickets);
      } else if (BILL_TYPE_FLIGHT_REFUND.equalsIgnoreCase(billInfo.getBillType())) {
        List<BillFlightRefundTicket> tickets = searchBillFlightRefundTickets(em, enterpriseId, billInfo.getBillNum());
        billInfo.setRefundTickets(tickets);
      } else if (BILL_TYPE_FLIGHT_CHANGE.equalsIgnoreCase(billInfo.getBillType())) {
        List<BillChangeOrder> tickets = searchBillChangeOrders(em, enterpriseId, billInfo.getBillNum());
        billInfo.setChangeOrders(tickets);
      } else if (BILL_TYPE_VAS.equalsIgnoreCase(billInfo.getBillType())) {
        billInfo.setVasOrders(doSearchBillVasOrders(enterpriseId, billInfo.getBillNum()));
      }
    }

    return billInfo;
  }

  protected List<BillFlightTicket> searchBillFlightTickets(EntityManager em, int enterpriseId, String billNum) {
    List<BillFlightTicket> tickets = em.createQuery("select o from BillFlightTicket o " +
            "where o.enterpriseId = :enterpriseId " +
            "and o.billNum = :billNum order by o.ticketNo", BillFlightTicket.class)
            .setParameter("enterpriseId", enterpriseId)
            .setParameter("billNum", billNum)
            .getResultList();

    //获取票号下面的详情
    for (BillFlightTicket ticket : tickets) {
      List<BillFlightTicketDetail> details = searchBillFlightTicketDetails(em, enterpriseId, ticket);
      ticket.setDetails(details);
    }

    return tickets;
  }

  protected List<BillFlightTicketDetail> searchBillFlightTicketDetails(EntityManager em, int enterpriseId, BillFlightTicket ticket) {
    return em.createQuery("select o from BillFlightTicketDetail o " +
            " where o.enterpriseId = :enterpriseId and o.balanceCode = :balanceCode and o.ticketNo = :ticketNo order by o.segOrd", BillFlightTicketDetail.class)
            .setParameter("enterpriseId", enterpriseId)
            .setParameter("balanceCode", ticket.getBalanceCode())
            .setParameter("ticketNo", ticket.getTicketNo())
            .getResultList();
  }

  protected List<BillFlightRefundTicket> searchBillFlightRefundTickets(EntityManager em, int enterpriseId, String billNum) {
    return em.createQuery("select o from BillFlightRefundTicket o where o.enterpriseId = :enterpriseId and o.billNum = :billNum order by o.ticketNo", BillFlightRefundTicket.class)
            .setParameter("enterpriseId", enterpriseId)
            .setParameter("billNum", billNum)
            .getResultList();
  }

  protected List<BillChangeOrder> searchBillChangeOrders(EntityManager em, int enterpriseId, String billNum) {
    return em.createQuery("select o from BillChangeOrder o " +
            "where o.enterpriseId = :enterpriseId and o.billNum = :billNum order by o.ticketNo", BillChangeOrder.class)
            .setParameter("enterpriseId", enterpriseId)
            .setParameter("billNum", billNum)
            .getResultList();
  }

  protected List<BillVasOrder> doSearchBillVasOrders(int enterpriseId, String billNum) {
    List<BillVasOrder> list = em.createQuery("select o from BillVasOrder o where o.enterpriseId = :enterpriseId and o.billNum = :billNum order by o.id", BillVasOrder.class)
            .setParameter("enterpriseId", enterpriseId)
            .setParameter("billNum", billNum)
            .getResultList();

    for(BillVasOrder billVasOrder: list) {
      if (billVasOrder.getPsgCount() > 1) {
        List<BillVasOrderPassenger> psgList = em.createQuery("select o from BillVasOrderPassenger o " +
                "where o.enterpriseId = :enterpriseId and o.order.id = :orderId order by o.id", BillVasOrderPassenger.class)
                .setParameter("enterpriseId", enterpriseId)
                .setParameter("orderId", billVasOrder.getId())
                .getResultList();
        billVasOrder.setPassengers(psgList);
      }
    }

    return list;
  }
}
